#include <REGX52.H>
#include <INTRINS.H>

sbit OneWire_DQ=P3^7;

/**
  * @brief  单总线初始化
  * @param  
  * @retval 主机接收的应答状态  0：应答，1：未应答
  */
unsigned char OneWire_Init()
{
	unsigned char data i;	
	unsigned char AckBit;//应答位 返回值
	//1、初始化
	OneWire_DQ = 1; 
	//2、主机拉低总线 至少480us
	OneWire_DQ = 0;
	
	/*因为函数运行 函数循环也消耗时间，在微秒量级误差较大
	所以不封装延时函数直接调用*/
	_nop_();i = 227;while (--i); //Delay 500us
	
	//3、主机释放总线
	OneWire_DQ = 1;	
	//4、主机释放总线后，从机在15~60us时间内将总线拉低60~240us然后释放
	//所以主机在大于60us时间后对总线进行检测，可知从机是否相应
	_nop_();i = 29;while (--i);//Delay 70us
	//5、主机在70us后检测应答
	AckBit = OneWire_DQ;
	//6、应答流程总时间最少持续480us 主机已延迟70us，所以主机再延迟500us
	_nop_();i = 227;while (--i); //Delay 500us	
	
	return AckBit;
}

/**
  * @brief  单总线主机发送一位
  * @param  Bit 要发送的单字节
  * @retval 无
  */
void OneWire_SendBit(unsigned char Bit)
{
	unsigned char data i;
	OneWire_DQ = 1;	
	//1、先将总线拉低
	OneWire_DQ = 0;	
	i = 2;while (--i); //Delay 10us
	//2、此时若Bit为0，OneWire_DQ继续为0；若为1，OneWire_DQ变为1
	OneWire_DQ = Bit;
	//3、总时长不能低于60us
	_nop_();i = 20;while (--i); //Delay 50us
	OneWire_DQ = 1;		
}

/**
  * @brief  主机接收一位字节
  * @param  无
  * @retval 返回要接收的字节
  */
unsigned char OneWire_ReceiveBit()
{
	unsigned char Bit;
	unsigned char data i;
	//1、先将总线拉低1~15us
	OneWire_DQ = 0;	
	i = 2;while (--i); //Delay 5us
	//2、延时5us后释放总线
	OneWire_DQ = 1;	
	i = 2;while (--i); //Delay 5us
  //3、采样 应在主机将总线拉低的15us内读取	
	Bit = OneWire_DQ;
	//4、总时长不能低于60us	
	_nop_();i = 20;while (--i); //Delay 50us
	return Bit;
}

/**
  * @brief  发送一个字节
  * @param  Byte 要发送的字节 
  * @retval 无
  */
void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		OneWire_SendBit(Byte&(0x01<<i)); //从低位到高位写入
	}
}

/**
  * @brief  接收一个字节
  * @param  无
  * @retval 要接收的字节
  */
unsigned char OneWire_ReceiveByte()
{
	unsigned char i,Byte=0x00;
	for(i=0;i<8;i++)
	{
		if(OneWire_ReceiveBit()){Byte |= (0x01<<i);} //从低位到高位读出	
	}	
	return Byte;
}